#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "character.h"

QString ArmorMateryType; // 防具精通类型
const char* CharacterFilePath = "./character.json";
extern const char* EquipmentFilePath; // 在equipment.cpp文件中定义

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle(tr("DNF手游伤害计算工具"));
    ui->checkBox_clothArmor->setEnabled(false);
    ui->checkBox_leatherArmor->setEnabled(false);
    ui->checkBox_lightArmor->setEnabled(false);
    ui->checkBox_heavyArmor->setEnabled(false);
    ui->checkBox_platteArmor->setEnabled(false);
    // 添加职业信息
    addCharacter();
    // 没有json文件则创建一个
    createJsonFile();
    // 初始化界面
    initSoftware();
    // 计算最终伤害提升
    connect(ui->pushButton_finaldamage,&QPushButton::clicked,this,&MainWindow::computeFinalDamage);
    // 切换强化等级
    connect(ui->comboBox_reinforcement,&QComboBox::currentIndexChanged,this,&MainWindow::changeReinforcementLevel);
    // 切换职业和防具类型则显示对应的武器与防具
    connect(ui->comboBox_character,&QComboBox::currentIndexChanged,this,&MainWindow::armorMasteryOfCareer);
    connect(ui->comboBox_character,&QComboBox::currentIndexChanged,this,&MainWindow::readWeponAndArmorInfo);
    connect(ui->comboBox_armorType,&QComboBox::currentIndexChanged,this,&MainWindow::readWeponAndArmorInfo);
    // 切换装备则自动获取其数值并写入表格中
    connect(ui->comboBox_wepon,&QComboBox::currentIndexChanged,this,&MainWindow::updateFormValue);
    connect(ui->comboBox_armor,&QComboBox::currentIndexChanged,this,&MainWindow::updateFormValue);
    connect(ui->comboBox_jewelry,&QComboBox::currentIndexChanged,this,&MainWindow::updateFormValue);
    connect(ui->comboBox_auxiliary,&QComboBox::currentIndexChanged,this,&MainWindow::updateFormValue);
    // 勾选属性攻击选项时取反另一个选择框
    ui->checkBox_haveAttribute->setCheckState(Qt::Checked);
    connect(ui->checkBox_haveAttribute,&QCheckBox::clicked,ui->checkBox_noAttribute,&QCheckBox::toggle);
    connect(ui->checkBox_noAttribute,&QCheckBox::clicked,ui->checkBox_haveAttribute,&QCheckBox::toggle);
    connect(ui->checkBox_haveAttribute,&QCheckBox::clicked,this,&MainWindow::computeFinalDamage);
    connect(ui->checkBox_noAttribute,&QCheckBox::clicked,this,&MainWindow::computeFinalDamage);
    // 创建添加装备功能框
    mw_addEquip = new AddEquip(this);
    connect(ui->pushButton_equipment,&QPushButton::clicked,mw_addEquip,&AddEquip::exec);
    connect(mw_addEquip,&AddEquip::accepted,this,&MainWindow::readEquipmentJson);
}

MainWindow::~MainWindow()
{
    QFile jsonFile(CharacterFilePath);
    if(jsonFile.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        QJsonArray attributeArray;
        QJsonObject character {
                              {"力智", ui->lineEdit_STR->text().toInt()},
                              {"攻击", ui->lineEdit_ATK->text().toInt()},
                              {"暴击率", ui->lineEdit_CRIpro->text().toInt()},
                              {"暴击值", ui->lineEdit_CRIval->text().toInt()},
                              {"力智加成", ui->lineEdit_STRbonus->text().toInt()},
                              {"攻击加成", ui->lineEdit_ATKbonus->text().toInt()},
                              {"技攻加成", ui->lineEdit_SKIbonus->text().toInt()},
                              {"黄字加成", ui->lineEdit_DAMbonus->text().toInt()},
                              {"暴伤加成", ui->lineEdit_CRIDAMbonus->text().toInt()},
                              {"白字加成", ui->lineEdit_EXTDAMbonus->text().toInt()},
                              {"属白加成", ui->lineEdit_ELEEXTDAMbonus->text().toInt()},
                              {"属强", ui->lineEdit_ELEbonus->text().toInt()},
                              };
        attributeArray.append(character);

        QJsonDocument jsonDoc(attributeArray);
        jsonFile.write(jsonDoc.toJson());
        jsonFile.close();
    }
    else
    {
        qDebug() << tr("jsonFile open failed");
    }
    delete ui;
}

//添加角色
void MainWindow::addCharacter()
{
    CharacterClass mw_character;
    QList<QString>careerList = mw_character.subCareerList();
    for(const auto &name : careerList)
    {
        ui->comboBox_character->addItem(name);
    }
}

// 初始化软件
void MainWindow::initSoftware()
{
    mw_model = new QStandardItemModel(this);
    // 设置水平表头
    QStringList header;
    for (int column = 0; column < HorizontalHeaderMap.size(); ++column)
    {
        header << HorizontalHeaderMap[column];
    }
    mw_model->setHorizontalHeaderLabels(header);
    header.resize(0);
    // 设置垂直表头
    for (int row = 0; row < VerticalHeaderMap.size(); ++row)
    {
        header << VerticalHeaderMap[row];
    }
    mw_model->setVerticalHeaderLabels(header);
    for (int column = 0; column < HorizontalHeaderMap.size(); ++column)
    {
        for (int row = 0; row < VerticalHeaderMap.size(); ++row)
        {
            // 初始化表格内容为0
            mw_model->setItem(row,column,new QStandardItem(tr("0")));
        }
    }
    ui->tableView->setModel(mw_model);
    // 设置表格式
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::Stretch);
    ui->tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::Stretch);
    ui->tableView->setWordWrap(true);
    CenteredDelegate *delegate = new CenteredDelegate(ui->tableView); // 创建一个委托
    ui->tableView->setItemDelegate(delegate); // 通过委托设置文本居中格式

    // 从json文件获取装人物属性
    QFile jsonFile(CharacterFilePath);
    if(!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << tr("jsonFile open failed");
    }
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonFile.readAll());
    jsonFile.close();
    if (jsonDoc.isArray())
    {
        QJsonArray characterArray = jsonDoc.array();
        for (const QJsonValue &jsonValue : characterArray)
        {
            QJsonObject character = jsonValue.toObject();
            ui->lineEdit_STR->setText(QString::number(character["力智"].toInt()));
            ui->lineEdit_ATK->setText(QString::number(character["攻击"].toInt()));
            ui->lineEdit_CRIpro->setText(QString::number(character["暴击率"].toInt()));
            ui->lineEdit_CRIval->setText(QString::number(character["暴击值"].toInt()));
            ui->lineEdit_STRbonus->setText(QString::number(character["力智加成"].toInt()));
            ui->lineEdit_ATKbonus->setText(QString::number(character["攻击加成"].toInt()));
            ui->lineEdit_SKIbonus->setText(QString::number(character["技攻加成"].toInt()));
            ui->lineEdit_DAMbonus->setText(QString::number(character["黄字加成"].toInt()));
            ui->lineEdit_CRIDAMbonus->setText(QString::number(character["暴伤加成"].toInt()));
            ui->lineEdit_EXTDAMbonus->setText(QString::number(character["白字加成"].toInt()));
            ui->lineEdit_ELEEXTDAMbonus->setText(QString::number(character["属白加成"].toInt()));
            ui->lineEdit_ELEbonus->setText(QString::number(character["属强"].toInt()));
        }
    }
    else
    {
        informationHint(tr("character.json格式错误，无法读取\n请重新打开软件"));
        return;
    }
    // 把人物属性填入表格中
    addCharacterAttribute();

    // 读取装备信息到EquipmentInfo对象中
    // 武器与防具只读取与职业和防具类型对应的信息
    readEquipmentJson();
}

void MainWindow::readEquipmentJson()
{
    // 先清除combox里原来的装备信息
    ui->comboBox_wepon->clear();
    ui->comboBox_wepon->addItem("--武器--");
    ui->comboBox_armor->clear();
    ui->comboBox_armor->addItem("--防具--");
    ui->comboBox_jewelry->clear();
    ui->comboBox_jewelry->addItem("--首饰--");
    ui->comboBox_auxiliary->clear();
    ui->comboBox_auxiliary->addItem("--辅助装备--");
    // 再重新添加装备信息
    QFile jsonFile2(EquipmentFilePath);
    if(!jsonFile2.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        informationHint(tr("Equipment.json文件打开失败"));
        return;
    }
    QJsonDocument jsonDoc2 = QJsonDocument::fromJson(jsonFile2.readAll());
    jsonFile2.close();
    if(!jsonDoc2.isObject())
    {
        informationHint(tr("json格式错误，读取信息失败"));
        return;
    }
    QJsonObject rootObject = jsonDoc2.object();
    // 读取武器信息
    QString character = ui->comboBox_character->currentText();
    CharacterClass mw_character;
    QString baseCareer = mw_character.whatsCareer(character).first;
    QJsonObject weponObject = rootObject["武器"].toObject();
    QJsonArray weponArray = weponObject[baseCareer].toArray();
    for(const QJsonValue &value : weponArray)
    {
        QString weponName = value["武器名称"].toString();
        ui->comboBox_wepon->addItem(weponName);
    }
    // 读取防具信息
    QString armorType = ui->comboBox_armorType->currentText();
    QJsonObject armorObject = rootObject["防具"].toObject();
    QJsonArray armorArray = armorObject[armorType].toArray();
    for(const QJsonValue &value : armorArray)
    {
        QString armorName = value["防具套装名称"].toString();
        ui->comboBox_armor->addItem(armorName);
    }
    // 读取首饰信息
    QJsonArray jewArray = rootObject["首饰"].toArray();
    for(const QJsonValue &value : jewArray)
    {
        QString jewName = value["首饰套装名称"].toString();
        ui->comboBox_jewelry->addItem(jewName);
    }
    // 读取辅助装备信息
    QJsonArray auxArray = rootObject["辅助装备"].toArray();
    for(const QJsonValue &value : auxArray)
    {
        QString auxName = value["辅助装备名称"].toString();
        ui->comboBox_auxiliary->addItem(auxName);
    }
}

void MainWindow::createJsonFile()
{
    // 创建equipment.json文件
    const QString equipmentFileName = EquipmentFilePath;
    if(!QFile::exists(equipmentFileName))
    {
        QJsonObject rootObject; // 把所有对象都添加到根对象
        // 创建武器信息
        QJsonObject weponObject; // 此对象用于存放各职业武器
        QJsonArray knightWepon; // 此array存放用于存放鬼剑士的武器信息
        QJsonArray shooterWepon; // 此array存放用于存放鬼剑士的武器信息
        QJsonArray fighterWepon; // 此array存放用于存放鬼剑士的武器信息
        QJsonArray clergyWepon; // 此array存放用于存放鬼剑士的武器信息
        QJsonArray enchanterWepon; // 此array存放用于存放鬼剑士的武器信息
        weponObject["鬼剑士"] = knightWepon;
        weponObject["神枪手"] = shooterWepon;
        weponObject["格斗家"] = fighterWepon;
        weponObject["圣职者"] = clergyWepon;
        weponObject["魔法师"] = enchanterWepon;
        rootObject["武器"] = weponObject;
        // 创建防具信息
        QJsonObject armorObject; // 此对象用于存放防具类型
        QJsonArray clothArmor; // 此array存放用于存放布甲信息
        QJsonArray leatherArmor; // 此array存放用于存放皮甲信息
        QJsonArray lightArmor; // 此array存放用于存放轻甲信息
        QJsonArray heavyArmor; // 此array存放用于存放重甲信息
        QJsonArray plateArmor; // 此array存放用于存放板甲信息
        armorObject["布甲"] = clothArmor;
        armorObject["皮甲"] = leatherArmor;
        armorObject["轻甲"] = lightArmor;
        armorObject["重甲"] = heavyArmor;
        armorObject["板甲"] = plateArmor;
        rootObject["防具"] = armorObject;
        // 创建首饰信息
        QJsonArray jewelryObject; // 此array存放用于存放各首饰信息
        rootObject["首饰"] = jewelryObject;
        // 创建辅助装备信息
        QJsonArray auxiliaryObject; // 此array用于存放各辅助装备信息
        rootObject["辅助装备"] = auxiliaryObject;
        // 创建json文件并写入
        QJsonDocument jsonDoc(rootObject);
        QFile jsonFile(equipmentFileName);
        if(jsonFile.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            jsonFile.write(jsonDoc.toJson(QJsonDocument::Indented)); // 以美化格式写入
            jsonFile.close();
        }
        else
        {
            qDebug() << "写入json文件失败";
        }
    }
    // 创建character.json文件
    const QString characterFileName = CharacterFilePath;
    if(!QFile::exists(characterFileName))
    {
        QJsonArray attributeArray;
        QJsonObject character {
                              {"力智", ui->lineEdit_STR->text().toInt()},
                              {"攻击", ui->lineEdit_ATK->text().toInt()},
                              {"暴击率", ui->lineEdit_CRIpro->text().toInt()},
                              {"暴击值", ui->lineEdit_CRIval->text().toInt()},
                              {"力智加成", ui->lineEdit_STRbonus->text().toInt()},
                              {"攻击加成", ui->lineEdit_ATKbonus->text().toInt()},
                              {"技攻加成", ui->lineEdit_SKIbonus->text().toInt()},
                              {"黄字加成", ui->lineEdit_DAMbonus->text().toInt()},
                              {"暴伤加成", ui->lineEdit_CRIDAMbonus->text().toInt()},
                              {"白字加成", ui->lineEdit_EXTDAMbonus->text().toInt()},
                              {"属白加成", ui->lineEdit_ELEEXTDAMbonus->text().toInt()},
                              {"属强", ui->lineEdit_ELEbonus->text().toInt()},
                              };
        attributeArray.append(character);
        // 创建json文件并写入
        QJsonDocument jsonDoc(attributeArray);
        QFile jsonFile(characterFileName);
        if(jsonFile.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            jsonFile.write(jsonDoc.toJson(QJsonDocument::Indented)); // 以美化格式写入
            jsonFile.close();
        }
        else
        {
            qDebug() << "写入json文件失败";
        }
    }

}

void MainWindow::addCharacterAttribute()
{
    // 要先把面板攻击力转换成基础攻击力
    strength = ui->lineEdit_STR->text().toInt();
    strengthBonus = ui->lineEdit_STRbonus->text().toInt();
    attack = ui->lineEdit_ATK->text().toInt();
    attackBonus = ui->lineEdit_ATKbonus->text().toInt();
    baseAttack = attack / computeSTRorINTCoefficient(strength,strengthBonus) / (1+attackBonus/100.0) + 0.5; // +0.5为四舍五入
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),0)->setText(QString::number(ui->lineEdit_STR->text().toInt() + RED_BADGE)); // 加上力量徽章
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),1)->setText(QString::number(baseAttack));
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),2)->setText(ui->lineEdit_CRIpro->text());
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),3)->setText(QString::number(ui->lineEdit_CRIval->text().toInt() + GREEN_BADGE)); // 加上暴击徽章
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),4)->setText(ui->lineEdit_STRbonus->text());
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),5)->setText(ui->lineEdit_ATKbonus->text());
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),6)->setText(ui->lineEdit_SKIbonus->text());
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),7)->setText(ui->lineEdit_DAMbonus->text());
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),8)->setText(ui->lineEdit_CRIDAMbonus->text());
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),9)->setText(ui->lineEdit_EXTDAMbonus->text());
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),10)->setText(ui->lineEdit_ELEEXTDAMbonus->text());
    mw_model->item(VerticalHeaderMap.key(tr("人物属性")),11)->setText(ui->lineEdit_ELEbonus->text());
}

void MainWindow::armorMasteryOfCareer()
{
    QComboBox *combox = qobject_cast<QComboBox*>(sender());
    CharacterClass mw_character;
    QString subCareerName = combox->currentText();
    ArmorMateryType = mw_character.whatsArmorMastery(subCareerName);
    if(ArmorMateryType == tr("布甲"))
    {
        ui->checkBox_clothArmor->setCheckState(Qt::Checked);
        ui->checkBox_leatherArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_lightArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_heavyArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_platteArmor->setCheckState(Qt::Unchecked);
    }
    else if(ArmorMateryType == tr("皮甲"))
    {
        ui->checkBox_clothArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_leatherArmor->setCheckState(Qt::Checked);
        ui->checkBox_lightArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_heavyArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_platteArmor->setCheckState(Qt::Unchecked);
    }
    else if(ArmorMateryType == tr("轻甲"))
    {
        ui->checkBox_clothArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_leatherArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_lightArmor->setCheckState(Qt::Checked);
        ui->checkBox_heavyArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_platteArmor->setCheckState(Qt::Unchecked);
    }
    else if(ArmorMateryType == tr("重甲"))
    {
        ui->checkBox_clothArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_leatherArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_lightArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_heavyArmor->setCheckState(Qt::Checked);
        ui->checkBox_platteArmor->setCheckState(Qt::Unchecked);
    }
    else if(ArmorMateryType == tr("板甲"))
    {
        ui->checkBox_clothArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_leatherArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_lightArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_heavyArmor->setCheckState(Qt::Unchecked);
        ui->checkBox_platteArmor->setCheckState(Qt::Checked);
    }
}

// 弹出提示框
void MainWindow::informationHint(QString info)
{
    QMessageBox::information(this,tr("提示"),info);
}

// 切换职业或切换防具类型时读取对应装备信息
void MainWindow::readWeponAndArmorInfo()
{
    QComboBox *combox = qobject_cast<QComboBox*>(sender());
    QFile jsonFile(EquipmentFilePath);
    if(!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        informationHint(tr("Equipment.json文件打开失败"));
        return;
    }
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonFile.readAll());
    if(!jsonDoc.isObject())
    {
        informationHint(tr("json格式错误，读取信息失败"));
        return;
    }
    QJsonObject rootObject = jsonDoc.object();
    // 读取武器信息
    if(combox == ui->comboBox_character)
    {
        CharacterClass mw_character; // 各转职对应的基础职业和伤害类型,用于选择对应武器和计算伤害
        ui->comboBox_wepon->clear();
        ui->comboBox_wepon->addItem("--武器--");
        QString character = ui->comboBox_character->currentText();
        QString baseCareer = mw_character.whatsCareer(character).first;
        QJsonObject weponObject = rootObject["武器"].toObject();
        QJsonArray weponArray = weponObject[baseCareer].toArray();
        for(const QJsonValue &value : weponArray)
        {
            QString weponName = value["武器名称"].toString();
            ui->comboBox_wepon->addItem(weponName);
        }
    }
    // 读取防具信息
    if(combox == ui->comboBox_armorType)
    {
        ui->comboBox_armor->clear();
        ui->comboBox_armor->addItem("--防具--");
        QString armorType = ui->comboBox_armorType->currentText();
        QJsonObject armorObject = rootObject["防具"].toObject();
        QJsonArray armorArray = armorObject[armorType].toArray();
        for(const QJsonValue &value : armorArray)
        {
            QString armorName = value["防具套装名称"].toString();
            ui->comboBox_armor->addItem(armorName);
        }
    }
}

// 切换强化等级时变更对应属性数值
void MainWindow::changeReinforcementLevel()
{
    QComboBox *combobox = qobject_cast<QComboBox*>(sender());
    if(combobox->currentText() == tr("无强化"))
    {
        int oldValue, newValue;
        // 武器攻击力
        if(ui->comboBox_wepon->currentIndex() != 0)
        {
            oldValue = mw_model->item(VerticalHeaderMap.key(tr("武器")),
                                      HorizontalHeaderMap.key(tr("物攻/魔攻")))->text().toInt();
            newValue = oldValue - WEPON_REINFORCEMENT_20;
            mw_model->item(VerticalHeaderMap.key(tr("武器")),1)->setText(tr("%1").arg(newValue));
        }
        // 防具力智
        if(ui->comboBox_armor->currentIndex() != 0)
        {
            oldValue = mw_model->item(VerticalHeaderMap.key(tr("防具套装")),
                                      HorizontalHeaderMap.key(tr("力量/智力")))->text().toInt();
            newValue = oldValue - ARMOR_REINFORCEMENT_20;
            mw_model->item(VerticalHeaderMap.key(tr("防具套装")),
                           HorizontalHeaderMap.key(tr("力量/智力")))->setText(tr("%1").arg(newValue));
        }
        // 首饰力智
        if(ui->comboBox_jewelry->currentIndex() != 0)
        {
            oldValue = mw_model->item(VerticalHeaderMap.key(tr("首饰套装")),
                                      HorizontalHeaderMap.key(tr("力量/智力")))->text().toInt();
            newValue = oldValue - JEWELRY_REINFORCEMENT_20;
            mw_model->item(VerticalHeaderMap.key(tr("首饰套装")),
                           HorizontalHeaderMap.key(tr("力量/智力")))->setText(tr("%1").arg(newValue));
        }
        // 辅助装备力智
        if(ui->comboBox_auxiliary->currentIndex() != 0)
        {
            oldValue = mw_model->item(VerticalHeaderMap.key(tr("辅助装备")),
                                      HorizontalHeaderMap.key(tr("力量/智力")))->text().toInt();
            newValue = oldValue - AUXILIARY_REINFORCEMENT_20;
            mw_model->item(VerticalHeaderMap.key(tr("辅助装备")),
                           HorizontalHeaderMap.key(tr("力量/智力")))->setText(tr("%1").arg(newValue));
        }
    }
    else if(combobox->currentText() == tr("强化+20"))
    {
        int oldValue, newValue;
        // 武器攻击力
        if(ui->comboBox_wepon->currentIndex() != 0)
        {
            oldValue = mw_model->item(VerticalHeaderMap.key(tr("武器")),
                                      HorizontalHeaderMap.key(tr("物攻/魔攻")))->text().toInt();
            newValue = oldValue + WEPON_REINFORCEMENT_20;
            mw_model->item(VerticalHeaderMap.key(tr("武器")),1)->setText(tr("%1").arg(newValue));
        }
        // 防具力智
        if(ui->comboBox_armor->currentIndex() != 0)
        {
            oldValue = mw_model->item(VerticalHeaderMap.key(tr("防具套装")),
                                      HorizontalHeaderMap.key(tr("力量/智力")))->text().toInt();
            newValue = oldValue + ARMOR_REINFORCEMENT_20;
            mw_model->item(VerticalHeaderMap.key(tr("防具套装")),
                           HorizontalHeaderMap.key(tr("力量/智力")))->setText(tr("%1").arg(newValue));
        }
        // 首饰力智
        if(ui->comboBox_jewelry->currentIndex() != 0)
        {
            oldValue = mw_model->item(VerticalHeaderMap.key(tr("首饰套装")),
                                      HorizontalHeaderMap.key(tr("力量/智力")))->text().toInt();
            newValue = oldValue + JEWELRY_REINFORCEMENT_20;
            mw_model->item(VerticalHeaderMap.key(tr("首饰套装")),
                           HorizontalHeaderMap.key(tr("力量/智力")))->setText(tr("%1").arg(newValue));
        }
        // 辅助装备力智
        if(ui->comboBox_auxiliary->currentIndex() != 0)
        {
            oldValue = mw_model->item(VerticalHeaderMap.key(tr("辅助装备")),
                                      HorizontalHeaderMap.key(tr("力量/智力")))->text().toInt();
            newValue = oldValue + AUXILIARY_REINFORCEMENT_20;
            mw_model->item(VerticalHeaderMap.key(tr("辅助装备")),
                           HorizontalHeaderMap.key(tr("力量/智力")))->setText(tr("%1").arg(newValue));
        }
    }
    updateFormValue();
}

// 获取装备数值
QList<int> MainWindow::readEquipmentValue(QString equipmentType, QString equipmentName)
{
    QFile jsonFile(EquipmentFilePath);
    if(!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        informationHint(tr("equipment.json打开失败"));
        return QList<int>();
    }
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonFile.readAll());
    jsonFile.close();
    if(!jsonDoc.isObject())
    {
        informationHint(tr("json格式错误，读取信息失败"));
        return QList<int>();
    }
    QJsonObject rootObject = jsonDoc.object();
    QString character = ui->comboBox_character->currentText();
    CharacterClass mw_character;
    QString damageType = mw_character.whatsCareer(character).second;
    if(equipmentType == tr("武器"))
    {
        QJsonObject weponObject = rootObject["武器"].toObject();
        QString baseCareer = mw_character.whatsCareer(character).first;
        QJsonArray weponArray = weponObject[baseCareer].toArray();
        QList<int>equipmentValue;
        for(const QJsonValue &value : weponArray)
        {
            if(value["武器名称"].toString()==equipmentName && damageType=="物理伤害")
            {
                equipmentValue.push_back(value[_STR].toInt());
                equipmentValue.push_back(value[_PATK].toInt());
                equipmentValue.push_back(value[_PCRIP].toInt());
                equipmentValue.push_back(value[_PCRIV].toInt());
                equipmentValue.push_back(value[_STRB].toInt());
                equipmentValue.push_back(value[_PATKB].toInt());
                equipmentValue.push_back(value[_SKIB].toInt());
                equipmentValue.push_back(value[_DAMB].toInt());
                equipmentValue.push_back(value[_CRIDAMB].toInt());
                equipmentValue.push_back(value[_EXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEEXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEB].toInt());
            }
            else if(value["武器名称"].toString()==equipmentName && damageType=="魔法伤害")
            {
                equipmentValue.push_back(value[_INT].toInt());
                equipmentValue.push_back(value[_MATK].toInt());
                equipmentValue.push_back(value[_MCRIP].toInt());
                equipmentValue.push_back(value[_MCRIV].toInt());
                equipmentValue.push_back(value[_INTB].toInt());
                equipmentValue.push_back(value[_MATKB].toInt());
                equipmentValue.push_back(value[_SKIB].toInt());
                equipmentValue.push_back(value[_DAMB].toInt());
                equipmentValue.push_back(value[_CRIDAMB].toInt());
                equipmentValue.push_back(value[_EXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEEXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEB].toInt());
            }
        }
        return equipmentValue;
    }
    else if(equipmentType == tr("防具"))
    {
        QJsonObject armorObject = rootObject["防具"].toObject();
        QString armorType = ui->comboBox_armorType->currentText();
        QJsonArray armorArray = armorObject[armorType].toArray();
        QList<int>equipmentValue;
        for(const QJsonValue &value : armorArray)
        {
            if(value["防具套装名称"].toString()==equipmentName && damageType=="物理伤害")
            {
                equipmentValue.push_back(value[_STR].toInt());
                equipmentValue.push_back(value[_PATK].toInt());
                equipmentValue.push_back(value[_PCRIP].toInt());
                equipmentValue.push_back(value[_PCRIV].toInt());
                equipmentValue.push_back(value[_STRB].toInt());
                equipmentValue.push_back(value[_PATKB].toInt());
                equipmentValue.push_back(value[_SKIB].toInt());
                equipmentValue.push_back(value[_DAMB].toInt());
                equipmentValue.push_back(value[_CRIDAMB].toInt());
                equipmentValue.push_back(value[_EXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEEXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEB].toInt());
            }
            else if(value["防具套装名称"].toString()==equipmentName && damageType=="魔法伤害")
            {
                equipmentValue.push_back(value[_INT].toInt());
                equipmentValue.push_back(value[_MATK].toInt());
                equipmentValue.push_back(value[_MCRIP].toInt());
                equipmentValue.push_back(value[_MCRIV].toInt());
                equipmentValue.push_back(value[_INTB].toInt());
                equipmentValue.push_back(value[_MATKB].toInt());
                equipmentValue.push_back(value[_SKIB].toInt());
                equipmentValue.push_back(value[_DAMB].toInt());
                equipmentValue.push_back(value[_CRIDAMB].toInt());
                equipmentValue.push_back(value[_EXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEEXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEB].toInt());
            }
        }
        return equipmentValue;
    }
    else if(equipmentType == tr("首饰"))
    {
        QJsonArray jewelryArray = rootObject["首饰"].toArray();
        QList<int>equipmentValue;
        for(const QJsonValue &value : jewelryArray)
        {
            if(value["首饰套装名称"].toString()==equipmentName && damageType=="物理伤害")
            {
                equipmentValue.push_back(value[_STR].toInt());
                equipmentValue.push_back(value[_PATK].toInt());
                equipmentValue.push_back(value[_PCRIP].toInt());
                equipmentValue.push_back(value[_PCRIV].toInt());
                equipmentValue.push_back(value[_STRB].toInt());
                equipmentValue.push_back(value[_PATKB].toInt());
                equipmentValue.push_back(value[_SKIB].toInt());
                equipmentValue.push_back(value[_DAMB].toInt());
                equipmentValue.push_back(value[_CRIDAMB].toInt());
                equipmentValue.push_back(value[_EXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEEXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEB].toInt());
            }
            else if(value["首饰套装名称"].toString()==equipmentName && damageType=="魔法伤害")
            {
                equipmentValue.push_back(value[_INT].toInt());
                equipmentValue.push_back(value[_MATK].toInt());
                equipmentValue.push_back(value[_MCRIP].toInt());
                equipmentValue.push_back(value[_MCRIV].toInt());
                equipmentValue.push_back(value[_INTB].toInt());
                equipmentValue.push_back(value[_MATKB].toInt());
                equipmentValue.push_back(value[_SKIB].toInt());
                equipmentValue.push_back(value[_DAMB].toInt());
                equipmentValue.push_back(value[_CRIDAMB].toInt());
                equipmentValue.push_back(value[_EXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEEXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEB].toInt());
            }
        }
        return equipmentValue;
    }
    else if(equipmentType == tr("辅助装备"))
    {
        QJsonArray auxiliaryArray = rootObject["辅助装备"].toArray();
        QList<int>equipmentValue;
        for(const QJsonValue &value : auxiliaryArray)
        {
            if(value["辅助装备名称"].toString()==equipmentName && damageType=="物理伤害")
            {
                equipmentValue.push_back(value[_STR].toInt());
                equipmentValue.push_back(value[_PATK].toInt());
                equipmentValue.push_back(value[_PCRIP].toInt());
                equipmentValue.push_back(value[_PCRIV].toInt());
                equipmentValue.push_back(value[_STRB].toInt());
                equipmentValue.push_back(value[_PATKB].toInt());
                equipmentValue.push_back(value[_SKIB].toInt());
                equipmentValue.push_back(value[_DAMB].toInt());
                equipmentValue.push_back(value[_CRIDAMB].toInt());
                equipmentValue.push_back(value[_EXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEEXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEB].toInt());
            }
            else if(value["辅助装备名称"].toString()==equipmentName && damageType=="魔法伤害")
            {
                equipmentValue.push_back(value[_INT].toInt());
                equipmentValue.push_back(value[_MATK].toInt());
                equipmentValue.push_back(value[_MCRIP].toInt());
                equipmentValue.push_back(value[_MCRIV].toInt());
                equipmentValue.push_back(value[_INTB].toInt());
                equipmentValue.push_back(value[_MATKB].toInt());
                equipmentValue.push_back(value[_SKIB].toInt());
                equipmentValue.push_back(value[_DAMB].toInt());
                equipmentValue.push_back(value[_CRIDAMB].toInt());
                equipmentValue.push_back(value[_EXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEEXTDAMB].toInt());
                equipmentValue.push_back(value[_ELEB].toInt());
            }
        }
        return equipmentValue;
    }
    return QList<int>();
}

// 把装备数值写入表格并计算伤害
void MainWindow::updateFormValue()
{
    if(ui->comboBox_wepon->currentIndex() != 0)
    {
        QList<int>eqv = readEquipmentValue(tr("武器"),ui->comboBox_wepon->currentText());
        if(eqv.isEmpty())
        {
            return;
        }
        for (int column = 0; column < HorizontalHeaderMap.size(); ++column)
        {
            if(ui->comboBox_reinforcement->currentText() == tr("无强化"))
            {
                QString value = tr("%1").arg(eqv[column]);
                mw_model->item(VerticalHeaderMap.key(tr("武器")),column)->setText(value);
            }
            else if(ui->comboBox_reinforcement->currentText() == tr("强化+20"))
            {
                if(column == 1) // 按武器+20计算攻击力
                {
                    QString value = tr("%1").arg(eqv[column] + WEPON_REINFORCEMENT_20);
                    mw_model->item(VerticalHeaderMap.key(tr("武器")),column)->setText(value);
                }
                else
                {
                    QString value = tr("%1").arg(eqv[column]);
                    mw_model->item(VerticalHeaderMap.key(tr("武器")),column)->setText(value);
                }
            }
        }
    }
    else
    {
        for (int column = 0; column < HorizontalHeaderMap.size(); ++column)
        {
            mw_model->item(VerticalHeaderMap.key(tr("武器")),column)->setText(tr("0"));
        }
    }

    if(ui->comboBox_armor->currentIndex() != 0)
    {
        QList<int>eqv = readEquipmentValue(tr("防具"),ui->comboBox_armor->currentText());
        if(eqv.isEmpty())
        {
            return;
        }
        for (int column = 0; column < HorizontalHeaderMap.size(); ++column)
        {
            if(ui->comboBox_reinforcement->currentText() == tr("无强化"))
            {
                if(column == 0)
                {
                    QString value;
                    if(ui->comboBox_armorType->currentText() == ArmorMateryType)
                    {
                        value = tr("%1").arg(eqv[column] + ARMOR_MASTERY);
                    }
                    else
                    {
                        value = tr("%1").arg(eqv[column]);
                    }
                    mw_model->item(VerticalHeaderMap.key(tr("防具套装")),column)->setText(value);
                }
                else
                {
                    QString value = tr("%1").arg(eqv[column]);
                    mw_model->item(VerticalHeaderMap.key(tr("防具套装")),column)->setText(value);
                }

            }
            else if(ui->comboBox_reinforcement->currentText() == tr("强化+20"))
            {
                if(column == 0) // 按5套防具+20计算力智
                {
                    QString value;
                    if(ui->comboBox_armorType->currentText() == ArmorMateryType)
                    {
                        value = tr("%1").arg(eqv[column] + ARMOR_REINFORCEMENT_20
                                             + ARMOR_MASTERY);
                    }
                    else
                    {
                        value = tr("%1").arg(eqv[column] + ARMOR_REINFORCEMENT_20);
                    }
                    mw_model->item(VerticalHeaderMap.key(tr("防具套装")),column)->setText(value);
                }
                else
                {
                    QString value = tr("%1").arg(eqv[column]);
                    mw_model->item(VerticalHeaderMap.key(tr("防具套装")),column)->setText(value);
                }
            }
        }
    }
    else
    {
        for (int column = 0; column < HorizontalHeaderMap.size(); ++column)
        {
            mw_model->item(VerticalHeaderMap.key(tr("防具套装")),column)->setText(tr("0"));
        }
    }

    if(ui->comboBox_jewelry->currentIndex() != 0)
    {
        QList<int>eqv = readEquipmentValue(tr("首饰"),ui->comboBox_jewelry->currentText());
        if(eqv.isEmpty())
        {
            return;
        }
        for (int column = 0; column < HorizontalHeaderMap.size(); ++column)
        {
            if(ui->comboBox_reinforcement->currentText() == tr("无强化"))
            {
                QString value = tr("%1").arg(eqv[column]);
                mw_model->item(VerticalHeaderMap.key(tr("首饰套装")),column)->setText(value);
            }
            else if(ui->comboBox_reinforcement->currentText() == tr("强化+20"))
            {
                if(column == 0) // 按3套首饰+20计算力智
                {
                    QString value = tr("%1").arg(eqv[column] + JEWELRY_REINFORCEMENT_20);
                    mw_model->item(VerticalHeaderMap.key(tr("首饰套装")),column)->setText(value);
                }
                else
                {
                    QString value = tr("%1").arg(eqv[column]);
                    mw_model->item(VerticalHeaderMap.key(tr("首饰套装")),column)->setText(value);
                }
            }
        }
    }
    else
    {
        for (int column = 0; column < HorizontalHeaderMap.size(); ++column)
        {
            mw_model->item(VerticalHeaderMap.key(tr("首饰套装")),column)->setText(tr("0"));
        }
    }

    if(ui->comboBox_auxiliary->currentIndex() != 0)
    {
        QList<int>eqv = readEquipmentValue(tr("辅助装备"),ui->comboBox_auxiliary->currentText());
        if(eqv.isEmpty())
        {
            return;
        }
        for (int column = 0; column < HorizontalHeaderMap.size(); ++column)
        {
            if(ui->comboBox_reinforcement->currentText() == tr("无强化"))
            {
                QString value = tr("%1").arg(eqv[column]);
                mw_model->item(VerticalHeaderMap.key(tr("辅助装备")),column)->setText(value);
            }
            else if(ui->comboBox_reinforcement->currentText() == tr("强化+20"))
            {
                if(column == 0) // 按辅助装备+20计算力智
                {
                    QString value = tr("%1").arg(eqv[column] + AUXILIARY_REINFORCEMENT_20);
                    mw_model->item(VerticalHeaderMap.key(tr("辅助装备")),column)->setText(value);
                }
                else
                {
                    QString value = tr("%1").arg(eqv[column]);
                    mw_model->item(VerticalHeaderMap.key(tr("辅助装备")),column)->setText(value);
                }
            }
        }
    }
    else
    {
        for (int column = 0; column < HorizontalHeaderMap.size(); ++column)
        {
            mw_model->item(VerticalHeaderMap.key(tr("辅助装备")),column)->setText(tr("0"));
        }
    }
    // 计算伤害并更新表格数值
    computeFinalDamage();
}

// 计算基础伤害
double MainWindow::computeBaseDamage()
{
    // 读取人物脱掉装备后的面板属性值
    strength = mw_model->item(0,0)->text().toInt();
    attack = mw_model->item(0,1)->text().toInt();
    criticalProbability = mw_model->item(0,2)->text().toInt();
    criticalValue = mw_model->item(0,3)->text().toInt();
    strengthBonus = mw_model->item(0,4)->text().toInt();
    attackBonus = mw_model->item(0,5)->text().toInt();
    skillDamageBonus = mw_model->item(0,6)->text().toInt();
    damageBonus = mw_model->item(0,7)->text().toInt();
    criticalDamageBonus = mw_model->item(0,8)->text().toInt();
    extraDamageBonus = mw_model->item(0,9)->text().toInt();
    elementExtraDamageBonus = mw_model->item(0,10)->text().toInt();
    elementAttributeBonus = mw_model->item(0,11)->text().toInt();
    // 力量系数
    double strengthCoefficient = computeSTRorINTCoefficient(strength,strengthBonus);
    // 攻击系数
    double attackCoefficient = computeAttackCoefficient(attack,attackBonus);
    // 技能系数
    double skillDamageCoefficient = computeSkillDamageCoefficient(skillDamageBonus);
    // 暴击期望
    double criticalStrikeCoefficient = computeCriticalStrikeCoefficient(criticalValue,criticalProbability,criticalDamageBonus);
    // 增伤系数
    double damageIncreaseCoefficient = computeDamageIncreaseCoefficient(damageBonus);
    // 属强系数
    int validElementBonus = elementAttributeBonus - ui->lineEdit_monster->text().toInt();
    double elementAttributeCoefficient = computeElementAttributeCoefficient(validElementBonus);
    // 附加伤害系数
    double extraDamageCoefficient = computeExtraDamageCoefficient(extraDamageBonus,elementAttributeCoefficient*elementExtraDamageBonus);
    // 计算人物基础伤害
    double baseDamage;
    if(ui->checkBox_haveAttribute->isChecked())
        baseDamage = 1 * attackCoefficient * strengthCoefficient * skillDamageCoefficient * criticalStrikeCoefficient *
                      damageIncreaseCoefficient * extraDamageCoefficient * elementAttributeCoefficient;
    else
        baseDamage = 1 * attackCoefficient * strengthCoefficient * skillDamageCoefficient * criticalStrikeCoefficient *
                      damageIncreaseCoefficient * extraDamageCoefficient * 1;
    if(baseDamage == 0)
        baseDamage = 1;
    return baseDamage;
}

// 计算最终伤害
void MainWindow::computeFinalDamage()
{
    // 更新表格中的人物属性
    addCharacterAttribute();
    // 计算力智
    strength = 0;
    // 装备力智
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        strength += mw_model->item(row,_strength)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    /*-----------*/
    // 计算双攻
    attack = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        attack += mw_model->item(row,_attack)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    /*-----------*/
    // 计算暴击值
    criticalValue = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        criticalValue += mw_model->item(row,_criticalValue)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    /*-----------*/
    // 计算暴击率
    criticalProbability = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        criticalProbability += mw_model->item(row,_criticalProbability)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    // 计算力智加成
    strengthBonus = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        strengthBonus += mw_model->item(row,_strengthBonus)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    /*-----------*/
    // 计算双攻加成
    attackBonus = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        attackBonus += mw_model->item(row,_attackBonus)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    // 计算技攻加成
    skillDamageBonus = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        skillDamageBonus += mw_model->item(row,_skillDamageBonus)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    /*-----------*/
    // 计算黄字加成
    damageBonus = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        damageBonus += mw_model->item(row,_damageBonus)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    /*-----------*/
    // 计算暴伤加成
    criticalDamageBonus = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        criticalDamageBonus += mw_model->item(row,_criticalDamageBonus)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    /*-----------*/
    // 计算白字加成
    extraDamageBonus = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        extraDamageBonus += mw_model->item(row,_extraDamageBonus)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    /*-----------*/
    // 计算属白加成
    elementExtraDamageBonus = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        elementExtraDamageBonus += mw_model->item(row,_elementExtraDamageBonus)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    /*-----------*/
    // 计算属强加成
    elementAttributeBonus = 0;
    for (int row = 0; row < VerticalHeaderMap.size()-1; ++row)
    {
        elementAttributeBonus += mw_model->item(row,_elementAttributeBonus)->text().toInt(&mw_isNumber);
        if(!mw_isNumber)
        {
            informationHint(tr("表格中存在非整数值"));
            return;
        }
    }
    /*-----填入面板数值-----*/
    int panelValue = 0;
    panelValue = strength * (1 + strengthBonus/100.0);
    mw_model->item(VerticalHeaderMap.size()-1,_strength)->setText(tr("%1").arg(panelValue));
    panelValue = attack * (1 + attackBonus/100.0) * computeSTRorINTCoefficient(strength,strengthBonus);
    mw_model->item(VerticalHeaderMap.size()-1,_attack)->setText(tr("%1").arg(panelValue));
    mw_model->item(VerticalHeaderMap.size()-1,_criticalProbability)->setText(tr("%1").arg(criticalProbability+criticalValue/23.7));
    mw_model->item(VerticalHeaderMap.size()-1,_criticalValue)->setText(tr("%1").arg(criticalValue));
    mw_model->item(VerticalHeaderMap.size()-1,_strengthBonus)->setText(tr("%1").arg(strengthBonus));
    mw_model->item(VerticalHeaderMap.size()-1,_attackBonus)->setText(tr("%1").arg(attackBonus));
    mw_model->item(VerticalHeaderMap.size()-1,_skillDamageBonus)->setText(tr("%1").arg(skillDamageBonus));
    mw_model->item(VerticalHeaderMap.size()-1,_damageBonus)->setText(tr("%1").arg(damageBonus));
    mw_model->item(VerticalHeaderMap.size()-1,_criticalDamageBonus)->setText(tr("%1").arg(criticalDamageBonus));
    mw_model->item(VerticalHeaderMap.size()-1,_extraDamageBonus)->setText(tr("%1").arg(extraDamageBonus));
    mw_model->item(VerticalHeaderMap.size()-1,_elementExtraDamageBonus)->setText(tr("%1").arg(elementExtraDamageBonus));
    mw_model->item(VerticalHeaderMap.size()-1,_elementAttributeBonus)->setText(tr("%1").arg(elementAttributeBonus));
    /*-----计算最终提升-----*/
    // 计算力智系数
    double strengthCoefficient = computeSTRorINTCoefficient(strength,strengthBonus);
    // 计算攻击系数
    double attackCoefficient = computeAttackCoefficient(attack,attackBonus);
    // 计算技攻
    double skillDamageCoefficient = computeSkillDamageCoefficient(skillDamageBonus);
    // 计算暴击期望
    double criticalStrikeCoefficient = computeCriticalStrikeCoefficient(criticalValue,criticalProbability,criticalDamageBonus);
    // 计算增伤
    double damageIncreaseCoefficient = computeDamageIncreaseCoefficient(damageBonus);
    // 计算属强
    bool ok = true;
    int validElementBonus = elementAttributeBonus - ui->lineEdit_monster->text().toInt(&ok);
    if(!ok)
    {
        informationHint("怪物属抗需为整数值");
        return;
    }
    double elementAttributeCoefficient = computeElementAttributeCoefficient(validElementBonus);
    // 计算附加伤害
    double extraDamageCoefficient = computeExtraDamageCoefficient(extraDamageBonus,elementAttributeCoefficient*elementExtraDamageBonus);
    // 计算人物穿上装备后的最终伤害
    double finalDamage;
     if(ui->checkBox_haveAttribute->isChecked())
        finalDamage = 1 * attackCoefficient * strengthCoefficient * skillDamageCoefficient * criticalStrikeCoefficient *
                 damageIncreaseCoefficient * extraDamageCoefficient * elementAttributeCoefficient;
    else
        finalDamage = 1 * attackCoefficient * strengthCoefficient * skillDamageCoefficient * criticalStrikeCoefficient *
                      damageIncreaseCoefficient * extraDamageCoefficient * 1;
    // 最终提升 = finalDamage / baseDamage
    // 计算人物基础伤害
    double baseDamage = computeBaseDamage();
    double finalPromotion = finalDamage / baseDamage * 100;
    // 显示最终提升
    ui->finalDamage->setText(tr("最终提升比例：%1%").arg(finalPromotion,0,'G'));
    qDebug() << tr("最终伤害: %1").arg(finalDamage,0,'f',2);
}

/*-------------------------------------伤害公式计算-------------------------------------*/
// ①攻击系数 = 基础攻击*(1+双攻百分比之和) + 独立攻击
// 面板攻击力 = 基础攻击*(1+双攻百分比之和) * 力智系数
// 独立攻击 = 技能的固伤/技能的百分比
// ②力智系数 = 基础力智 * (1+力智百分比之和) / 250 + 1
// 面板力智 = 基础力智 * (1+力智百分比之和)
// ③技攻系数 = 1 + 技攻百分比之和
// ④暴击期望 = 1 + 暴击率 * (暴伤+50%), 暴击率 = 百分比暴击 + 3%人物初始暴击 + (暴击数值/23.7)%
// ⑤增伤系数 = 1 + 增伤之和
// ⑥属强系数 = 1.05 + 有效属强/220, 有效属强 = 人物属强 - 怪物属抗
// ⑦附加系数 = 1 + 附加伤害之和 * (1 + 3%*50%), 附加伤害之和 = 普白之和 + 属强系数*属白之和
// 最终伤害 = 基础伤害*①*②*③*④*⑤*⑥*⑦（①*②相当于面板攻击力 + 独立攻击*力智系数）

// 双攻
double MainWindow::computeAttackCoefficient(double value, double percent)
{
    const int independentAttack = 660; // 全部人物统一独立攻击
    return value * (1 + percent/100) + independentAttack;
}
// 力智
double MainWindow::computeSTRorINTCoefficient(double value, double percent)
{
    return (value * (1 + percent/100))/250 + 1;
}
// 技能攻击
double MainWindow::computeSkillDamageCoefficient(double percent)
{
    return 1 + percent/100;
}
// 爆伤
double MainWindow::computeCriticalStrikeCoefficient(double value, double probability, double damage)
{
    probability = probability/100 + 0.03 + value/23.7/100;
    if(probability >=1)
        return 1 + (damage/100 + 0.5);
    else
        return 1 + probability * (damage/100 + 0.5);
}
// 增伤
double MainWindow::computeDamageIncreaseCoefficient(double percent)
{
    return 1 + percent/100;
}
// 属强
double MainWindow::computeElementAttributeCoefficient(double value)
{
    return 1.05 + value/220;
}
// 附加伤害
double MainWindow::computeExtraDamageCoefficient(double percent1, double percent2)
{
    return 1 + (percent1/100 + percent2/100)*(1 + 0.03*0.5);
}
/*-----------------------------------------------------------------------------------*/


